package qa.tests;

import static java.util.ResourceBundle.getBundle;

import java.io.File;
import java.util.Locale;
import java.util.Set;
import java.util.TreeSet;

import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.reporting.AbstractMavenReportRenderer;

class TestTestReportRenderer extends AbstractMavenReportRenderer {

    static final String COLOR_FAIL = "#F02020";

    private static interface StatisticCounter {
        int count(Statistic statistic);
    }
    
    private final Locale locale;

    private final File outputDir;

    public TestTestReportRenderer(Sink sink, Locale locale, File outputDir) {
        super(sink);
        this.locale = locale;
        this.outputDir = outputDir;
    }

    @Override
    public String getTitle() {
        return getBundle(TestTestPluginInReport.BUNDLE_FILE, locale).getString("title");
    }

    @Override
    protected void renderBody() {
        File[] files = outputDir.listFiles();
        Set<Statistic> stats = new TreeSet<Statistic>(new AssertlessOnTopComparator());
        if (files != null) {
            for (File file : files) {
                stats.add(Statistics.fromFile(file));
            }
        }
        startSection("Summary");
            startTable();
                tableHeader(new String[]{"# Assertless Tests", "# Suspicious Tests", "# Instrumented Tests", "Percentage Assertless"});
                String assertlessTests = numberOfAssertlessTests(stats);
                tableRow(new String[]{assertlessTests, numberOfSuspiciousTests(stats), numberOfInstrumentedTests(stats), percentage(assertlessTests, stats.size())});
            endTable();
        endSection();
        
        startSection("Number Of Asserts");
        StringBuilder table = new StringBuilder();
        table.append("<table class=\"bodyTable\" style=\"width:auto;\">");
        int nthRow = 0;
        for (Statistic statistic : stats) {
            if(nthRow == 0) {
                tableHeader(table);
            }
            table.append("<tr class=\"" + cssClass(nthRow) + "\"" + styleFor(statistic) + ">")
                .append("<td>")
                    .append(statistic.getName())
                .append("</td>")
                .append("<td>")
                    .append(statistic.numberOfAsserts())
                .append("</td>")
            .append("</tr>");
            nthRow++;
        }
        table.append("</table>");
        sink.rawText(table.toString());
        endSection();
    }

    private String percentage(String assertlessTests, int size) {
        if(size == 0) {
            return "NA";
        }
        int x = Integer.valueOf(assertlessTests).intValue();
        int percentage = (x*100)/size;
        return percentage + "%";
    }

    private String numberOfInstrumentedTests(Set<Statistic> stats) {
        return String.valueOf(stats.size());
    }

    private String doCount(Set<Statistic> stats, StatisticCounter counter) {
        int count = 0;
        for (Statistic statistic : stats) {
            count += counter.count(statistic);
        }
            return String.valueOf(count);
    }
    
    private String numberOfSuspiciousTests(Set<Statistic> stats) {
        return doCount(stats, new StatisticCounter() {
            public int count(Statistic statistic) {
                return statistic.numberOfAsserts() == 1 ? 1 : 0;
            }
        });
    }

    private String numberOfAssertlessTests(Set<Statistic> stats) {
        return doCount(stats, new StatisticCounter() {
            public int count(Statistic statistic) {
                return statistic.numberOfAsserts() == 0 ? 1 : 0;
            }
        });
    }

    private void tableHeader(StringBuilder table) {
        table.append("<tr class=\"a\">");
            table.append("<th>");
                table.append("Method Name");
            table.append("</th>");
            table.append("<th>");
                table.append("# Asserts");
            table.append("</th>");
        table.append("</tr>");
    }

    private String styleFor(Statistic statistic) {
        if(statistic.numberOfAsserts() == 0) {
            return " style=\"background-color:"+failureColor()+"; width:100%; font-weight:bold;\" ";
        } else if(statistic.numberOfAsserts() == 1) {
            return " style=\"background-color:yellow; width:100%; font-weight:bold;\" ";
        }
        return "";
    }
    
    private String failureColor() {
        return COLOR_FAIL;
    }

    private String cssClass(int nthRow) {
        return (nthRow % 2 == 0 ? "b" : "a");
    }

}